<template>
  <div></div>
</template>

<script setup lang="ts" name="global-websocket">
import { ElNotification } from 'element-plus';
import { Session } from '/@/utils/storage';
import other from "/@/utils/other";

const emit = defineEmits(['message']);

const props = defineProps({
  uri: {
    type: String,
  },
});

const state = reactive({
  webSocket: ref(),
  lockReconnect: false,
  maxReconnect: 6,
  reconnectTime: 0,
  heartbeat: {
    interval: 30 * 1000,
    timeout: 10 * 1000,
    pingTimeoutObj: ref(),
    pongTimeoutObj: ref(),
    pingMessage: JSON.stringify({ type: 'ping' }),
  },
});

const token = computed(() => Session.getToken());

onMounted(() => initWebSocket());
onUnmounted(() => {
  state.webSocket.close();
  clearTimeoutObj(state.heartbeat);
});

// WebSocket 基础功能保持不变
const initWebSocket = () => {
  let wsUri = `ws://127.0.0.1:9999${other.adaptationUrl(props.uri)}?access_token=${token.value}`;
  state.webSocket = new WebSocket(wsUri);
  state.webSocket.onopen = onOpen;
  state.webSocket.onerror = onError;
  state.webSocket.onmessage = onMessage;
  state.webSocket.onclose = onClose;
};

const reconnect = () => {
  if (!token.value || state.lockReconnect ||
      (state.maxReconnect !== -1 && state.reconnectTime > state.maxReconnect)) {
    return;
  }
  state.lockReconnect = true;
  setTimeout(() => {
    state.reconnectTime++;
    initWebSocket();
    state.lockReconnect = false;
  }, 5000);
};

const clearTimeoutObj = (heartbeat: any) => {
  heartbeat.pingTimeoutObj && clearTimeout(heartbeat.pingTimeoutObj);
  heartbeat.pongTimeoutObj && clearTimeout(heartbeat.pongTimeoutObj);
};

const startHeartbeat = () => {
  const { webSocket, heartbeat } = state;
  clearTimeoutObj(heartbeat);
  heartbeat.pingTimeoutObj = setTimeout(() => {
    if (webSocket.readyState === 1) {
      webSocket.send(heartbeat.pingMessage);
      heartbeat.pongTimeoutObj = setTimeout(() => webSocket.close(), heartbeat.timeout);
    } else {
      reconnect();
    }
  }, heartbeat.interval);
};

// 消息处理核心逻辑
const onMessage = (msgEvent: any) => {
  startHeartbeat();
  const text = msgEvent.data;

  if (text.includes('pong')) return;

  try {
    const messageData = parseWebSocketMessage(text);
    emit('message', messageData);
    showNotification(messageData);
  } catch (error) {
    console.error('消息处理错误:', error);
    showErrorNotification(text);
  }
};

// 增强版消息解析
const parseWebSocketMessage = (rawData: string) => {
  try {
    const jsonData = typeof rawData === 'string' ? JSON.parse(rawData) : rawData;

    // 处理嵌套的 imagePath（可能是字符串形式的JSON）
    let imageUrl = '';
    if (jsonData.imageUrl) {
      try {
        const imgPath = typeof jsonData.imageUrl === 'string'
            ? JSON.parse(jsonData.imageUrl.replace(/'/g, '"'))
            : jsonData.imageUrl;
        imageUrl = imgPath.url || '';
      } catch {
        imageUrl = jsonData.imageUrl.url || jsonData.imageUrl || '';
      }
    }

    return {
      title: jsonData.title || '报警消息',
      devId: jsonData.devId || jsonData.deviceId || jsonData.equipmentId || '',
      messageType: jsonData.messageType || jsonData.type || jsonData.alarmType || '',
      messageDescribe: jsonData.message || jsonData.content || jsonData.messageDescribe || '',
      imageUrl: imageUrl || jsonData.imageUrl || jsonData.url || '',
      rawData
    };
  } catch (e) {
    // 字符串模式匹配增强
    const extractValue = (str, key) => {
      const match = str.match(new RegExp(`${key}=([^&,}\\s]+)`));
      return match ? match[1] : '';
    };

    return {
      title: '报警消息',
      devId: extractValue(rawData, 'devId') || extractValue(rawData, 'deviceId'),
      messageType: extractValue(rawData, 'messageType') || extractValue(rawData, 'type'),
      messageDescribe: extractValue(rawData, 'messageDescribe') || rawData,
      imageUrl: extractValue(rawData, 'imageUrl') || extractValue(rawData, 'url'),
      rawData
    };
  }
};

// 带图片的富文本通知
const showNotification = (messageData: any) => {
  const { title, devId, messageType, messageDescribe, imageUrl } = messageData;
  const hasImage = !!imageUrl;
  // 修正URL拼接方式
  const baseUrl = (import.meta.env.VITE_API_URL || '').replace(/\/$/, '');
  const imagePath = (imageUrl || '').replace(/^\//, '');
  const fullUrl =(imagePath ? `${baseUrl}/${imagePath}` : '');


  ElNotification.warning({
    title: title || '报警消息',
    message: `
      <div class="notification-content" style="
        display: flex;
        align-items: ${hasImage ? 'flex-start' : 'center'};
        gap: 15px;
        width: 100%;
        max-width: ${hasImage ? '500px' : '350px'};
      ">
        <div style="flex: 1; min-width: 0;">
          ${messageType ? `<p style="margin: 0 0 8px 0; font-weight: 500; color: #f56c6c;">类型: ${messageType}</p>` : ''}
          ${devId ? `<p style="margin: 0 0 6px 0; color: #666;">设备ID: ${devId}</p>` : ''}
          <p style="margin: 0; white-space: pre-wrap;">${messageDescribe || '收到新报警消息'}</p>
        </div>
        ${hasImage ? `
         <image
            src="${fullUrl}"
            style="width: 120px; height: 90px;"
            :preview-src-list="['${fullUrl}']"
          ></image>
        ` : ''}
      </div>
    `,
    dangerouslyUseHTMLString: true,
    duration: hasImage ? 8000 : 5000,
    offset: 60,
    customClass: 'custom-notification'
  });
};

// 错误通知
const showErrorNotification = (rawData: string) => {
  ElNotification.error({
    title: '消息解析失败',
    message: `原始数据: ${rawData.slice(0, 100)}${rawData.length > 100 ? '...' : ''}`,
    duration: 3000,
    offset: 60
  });
};
// const thisPageState = reactive({
//   imgBaseUrl: import.meta.env.VITE_API_URL,
// });
// 连接事件保持不变
const onOpen = () => {
  startHeartbeat();
  state.reconnectTime = 0;
};
const onError = reconnect;
const onClose = reconnect;
</script>

<style>
/* 全局通知样式调整 */
.custom-notification {
  width: auto !important;
  max-width: 500px !important;
}

.custom-notification .el-notification__content {
  margin: 8px 0 0 0 !important;
}

.custom-notification .el-image {
  transition: all 0.3s;
  border: 1px solid #eee;
  cursor: pointer;
}

.custom-notification .el-image:hover {
  transform: scale(1.03);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.image-error {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #999;
  font-size: 12px;
  background: #f5f5f5;
}

/* 移动端适配 */
@media (max-width: 768px) {
  .custom-notification {
    width: 90% !important;
  }
  .notification-content {
    flex-direction: column !important;
  }
  .custom-notification .el-image {
    width: 100% !important;
    height: auto !important;
    max-height: 150px;
    margin-top: 10px !important;
  }
}
</style>